// Gets the size of a file
function getFileSize(url)
{
    var cacheService = Components.classes["@mozilla.org/network/cache-service;1"].getService(Components.interfaces.nsICacheService);
    var cacheSession = null;
    var file         = null;
    var fileSize     = null;
    var readAccess   = Components.interfaces.nsICache.ACCESS_READ;

    // Try to get the file size from the HTTP cache
    try
    {
        cacheSession                      = cacheService.createSession("HTTP", 0, true);
        cacheSession.doomEntriesIfExpired = false;
        file                              = cacheSession.openCacheEntry(url, readAccess, false);

        // If there is a file
        if(file)
        {
            fileSize = file.dataSize;
        }
    }
    catch(exception)
    {
        // Try to get the file size from the FTP cache
        try
        {
            cacheSession                      = cacheService.createSession("FTP", 0, true);
            cacheSession.doomEntriesIfExpired = false;
            file                              = cacheSession.openCacheEntry(url, readAccess, false);

            // If there is a file
            if(file)
            {
                fileSize = file.dataSize;
            }
        }
        catch(exception)
        {
            fileSize = null;
        }
    }

    // If the file size could not be retrieved from the cache
    if(!fileSize)
    {
        // Try to download the file
        try
        {
            var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);

            fileSize = ioService.newChannelFromURI(ioService.newURI(url, null, null)).open().available();
        }
        catch(exception)
        {
            fileSize = null;
        }
    }

    return fileSize;
}

// Gets the uncompressed size of a file
function getUncompressedFileSize(url)
{
    var cacheService   = Components.classes["@mozilla.org/network/cache-service;1"].getService(Components.interfaces.nsICacheService);
    var cacheSession   = null;
    var file           = null;
    var fileCompressed = true;
    var fileSize       = null;
    var readAccess     = Components.interfaces.nsICache.ACCESS_READ;

    // Try to get the file size from the HTTP cache
    try
    {
        cacheSession                      = cacheService.createSession("HTTP", 0, true);
        cacheSession.doomEntriesIfExpired = false;
        file                              = cacheSession.openCacheEntry(url, readAccess, false);
    }
    catch(exception)
    {
        // Try to get the file size from the FTP cache
        try
        {
            cacheSession                      = cacheService.createSession("FTP", 0, true);
            cacheSession.doomEntriesIfExpired = false;
            file                              = cacheSession.openCacheEntry(url, readAccess, false);
        }
        catch(exception)
        {
            file = null;
        }
    }

    // If there is a file
    if(file)
    {
        var encoding        = null;
        var responseHeaders = null;

        // Try to get the cache encoding
        try
        {
            // Specific case-sensitive required
            encoding = file.getMetaDataElement("request-Accept-Encoding");
        }
        catch(exception)
        {
            encoding = null;

            // Try to get the response headers
            try
            {
                // Specific case-sensitive required
                responseHeaders = file.getMetaDataElement("response-head");
            }
            catch(exception)
            {
                responseHeaders = null;
            }
        }

        // If the cache is not GZIP encoded
        if((!encoding || encoding.indexOf("gzip") == -1) && (!responseHeaders || responseHeaders.indexOf("Content-Encoding: gzip") == -1))
        {
            fileCompressed = false;
        }
    }

    // If the file is compressed
    if(fileCompressed)
    {
        // Try to download the file
        try
        {
            var request = new XMLHttpRequest();

            request.open("get", url, false);
            request.send(null);

            fileSize = request.responseText.length;
        }
        catch(exception)
        {
            fileSize = null;
        }
    }

    return fileSize;
}

// Retrieves the source from the given URL
function retrieveSource(url)
{
    var source = null;

    // If the URL is not entirely generated
    if(url.indexOf("wyciwyg://") != 0)
    {
        var cacheService = Components.classes["@mozilla.org/network/cache-service;1"].getService(Components.interfaces.nsICacheService);
        var cacheSession = null;
        var file         = null;
        var readAccess   = Components.interfaces.nsICache.ACCESS_READ;

        // Try to get the file size from the HTTP cache
        try
        {
            cacheSession                      = cacheService.createSession("HTTP", 0, true);
            cacheSession.doomEntriesIfExpired = false;
            file                              = cacheSession.openCacheEntry(url, readAccess, false);
        }
        catch(exception)
        {
            // Try to get the file size from the FTP cache
            try
            {
                cacheSession                      = cacheService.createSession("FTP", 0, true);
                cacheSession.doomEntriesIfExpired = false;
                file                              = cacheSession.openCacheEntry(url, readAccess, false);
            }
            catch(exception)
            {
                file = null;
            }
        }

        // If there is a file
        if(file)
        {
            var encoding        = null;
            var responseHeaders = null;

            // Try to get the cache encoding
            try
            {
                // Specific case-sensitive required
                encoding = file.getMetaDataElement("request-Accept-Encoding");
            }
            catch(exception)
            {
                encoding = null;

                // Try to get the response headers
                try
                {
                    // Specific case-sensitive required
                    responseHeaders = file.getMetaDataElement("response-head");
                }
                catch(exception)
                {
                    responseHeaders = null;
                }
            }

            // If the cache is not GZIP encoded
            if((!encoding || encoding.indexOf("gzip") == -1) && (!responseHeaders || (responseHeaders.indexOf("Content-Encoding: deflate") == -1 && responseHeaders.indexOf("Content-Encoding: gzip") == -1)))
            {
                var inputStream      = file.openInputStream(0);
                var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);

                scriptableStream.init(inputStream);

                source = scriptableStream.read(scriptableStream.available());

                scriptableStream.close();
                inputStream.close();
            }
        }

        // If the source has not been loaded
        if(!source)
        {
            // Try to load the URL
            try
            {
                var request = new XMLHttpRequest();

                request.open("get", url, false);
                request.send(null);

                source = request.responseText;
            }
            catch(exception)
            {
                source = null;
            }
        }
    }

    return source;
}
